Skip to content

[build] Remove Step_PrepareProps; fold values into eng/Versions.props#11613

Merged
simonrozsival merged 7 commits into
mainfrom
jonathanpeppers/remove-step-prepareprops
Jun 11, 2026
Merged

[build] Remove Step_PrepareProps; fold values into eng/Versions.props#11613
simonrozsival merged 7 commits into
mainfrom
jonathanpeppers/remove-step-prepareprops

Conversation

@jonathanpeppers

@jonathanpeppers jonathanpeppers commented Jun 9, 2026

Copy link
Copy Markdown
Member

Continues the slow xaprepare removal. Recent precedent: #11568 (CopyExtraResultFilesForCI → YAML), #11580 (configuration.mk removal), #11529 (android-platform-support consolidation, which also dropped Step_PrepareExternalGitDependencies).

What

Step_PrepareProps generated external/Java.Interop/Configuration.Override.props (inside the submodule) by substituting two placeholders into build-tools/scripts/Configuration.Java.Interop.Override.in.props. The substituted properties (_XamarinAndroidCecilVersion, UtilityOutputFullPathCoreApps, XamarinAndroidToolsDirectory) are now supplied directly via the checked-in static file external/Java.Interop.override.props, which Java.Interop's own Directory.Build.props already auto-imports via the parent-dir convention added in dotnet/java-interop#872.

The shared version values (MonoCecilVersion, AndroidPackVersion, AndroidPackVersionSuffix) move into eng/Versions.props. Directory.Build.props and external/Java.Interop.override.props both <Import> it. No duplicate-import sentinel is needed because every code path that imports Configuration.props has already loaded Directory.Build.props (either via MSBuild auto-load or via the explicit <Import> in external/xamarin-android-tools.override.props).

MicrosoftAndroidSdkPackName stays in Configuration.props (it is OS-conditioned, not version-shaped, so it doesn't belong in Versions.props). The same 3-line OS-conditioned block is mirrored privately in external/Java.Interop.override.props as _MicrosoftAndroidSdkPackName, used only to compute UtilityOutputFullPathCoreApps for the Java.Interop build.

Also dropped:

  • Configurables.Paths.InstallMSBuildDir and its backing field — the only consumer was Step_PrepareProps.
  • The dead UtilityOutputFullPath line in the old template — Java.Interop's TargetFrameworkDependentValues.props unconditionally routes it to $(UtilityOutputFullPathCoreApps) anyway, so it was a no-op.

Updated build-tools/scripts/XAVersionInfo.targets (the GitBlame for <AndroidPackVersion> now points at eng/Versions.props) and Documentation/guides/HowToBranch.md to reflect the moves.

Why not just <Import> Directory.Build.props from the Java.Interop override?

That was the original idea. I prototyped it: importing dotnet/android's full props chain from external/Java.Interop.override.props flips DotNetTargetFrameworkVersion from 10.0 to 11.0 inside Java.Interop, and dotnet restore Java.Interop.csproj then fails with:

NETSDK1045: The current .NET SDK does not support targeting .NET 11.0

xamarin-android-tools.override.props gets away with the same trick only because its sole csproj sets AndroidToolsDisableMultiTargeting=true, which makes the TFM-clobber harmless. Java.Interop has no equivalent escape hatch.

eng/Versions.props is collision-free with Java.Interop (verified against the submodule sources — none of the existing entries collide), has no <Import> of its own, and is the safe minimal shared file.

Verification

On Windows:

  • dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj — 0 warnings, 0 errors.
  • From src/Xamarin.Android.Build.Tasks/: dotnet msbuild --getProperty:MonoCecilVersion,AndroidPackVersion,AndroidPackVersionSuffix,MicrosoftAndroidSdkPackName,MicrosoftAndroidSdkOutDir — values unchanged from baseline.
  • From external/Java.Interop/src/Java.Interop/:
    • dotnet msbuild --getProperty:DotNetTargetFramework,_XamarinAndroidCecilVersion,UtilityOutputFullPathCoreApps returns net10.0, 0.11.5, the expected packs/tools path.
    • dotnet restore Java.Interop.csproj succeeds (no NETSDK1045).

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

Continues the slow xaprepare removal (precedent: #11568, #11580, #11529).

`Step_PrepareProps` generated `external/Java.Interop/Configuration.Override.props`
inside the submodule by substituting two placeholders into
`build-tools/scripts/Configuration.Java.Interop.Override.in.props`. The same
properties are now supplied directly via `external/Java.Interop.override.props`
(a checked-in static file at `external/` that Java.Interop's `Directory.Build.props`
auto-imports via the parent-dir convention added in dotnet/java-interop#872).

The shared properties (`MonoCecilVersion`, `AndroidPackVersion`,
`MicrosoftAndroidSdkPackName`) move into `eng/Versions.props`, which is then
imported from `Directory.Build.props`, `Configuration.props`, and the
Java.Interop override. A `_XAVersionsPropsImported` sentinel guards each
import to avoid an MSB4011 duplicate-import warning.

Why not import dotnet/android's full `Directory.Build.props` from the Java.Interop
override? Because that flips `DotNetTargetFrameworkVersion` from 10.0 to 11.0
inside Java.Interop, causing `dotnet restore` to fail with
`NETSDK1045: The current .NET SDK does not support targeting .NET 11.0`.
`eng/Versions.props` is collision-free with Java.Interop and safe to import.

Also dropped:
* `Configurables.Paths.InstallMSBuildDir` and its backing field
  (only consumer was `Step_PrepareProps`).
* The dead `UtilityOutputFullPath` line in the old template -- Java.Interop's
  `TargetFrameworkDependentValues.props` unconditionally routes it to
  `$(UtilityOutputFullPathCoreApps)` anyway.

Updated `build-tools/scripts/XAVersionInfo.targets` and
`Documentation/guides/HowToBranch.md` to reflect that `AndroidPackVersion`
now lives in `eng/Versions.props`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 9, 2026 18:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Removes the xaprepare-driven Step_PrepareProps generation step by moving shared version properties into eng/Versions.props and wiring Java.Interop overrides to consume those values via a checked-in external/Java.Interop.override.props.

Changes:

  • Introduced eng/Versions.props as the shared location for MonoCecilVersion, AndroidPackVersion, and MicrosoftAndroidSdkPackName, plus an _XAVersionsPropsImported sentinel to avoid duplicate-import warnings.
  • Updated Directory.Build.props, Configuration.props, and external/Java.Interop.override.props to import eng/Versions.props (guarded by the sentinel).
  • Deleted the obsolete Step_PrepareProps and its template input file, and updated supporting docs/targets to reference the new source of AndroidPackVersion.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
external/Java.Interop.override.props Imports eng/Versions.props and provides static Java.Interop override properties (incl. Cecil version + tools path).
eng/Versions.props Adds sentinel + centralizes shared version properties for dotnet/android and Java.Interop.
Documentation/guides/HowToBranch.md Updates branching guidance to point AndroidPackVersion edits to eng/Versions.props.
Directory.Build.props Imports eng/Versions.props and removes local definitions now centralized there.
Configuration.props Imports eng/Versions.props with sentinel guard; removes duplicated MicrosoftAndroidSdkPackName definitions.
build-tools/xaprepare/xaprepare/Steps/Step_PrepareProps.cs Deletes the xaprepare step that generated Java.Interop override props.
build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.cs Removes the deleted step from the standard scenario.
build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs Removes InstallMSBuildDir path that was only used by the deleted step.
build-tools/scripts/XAVersionInfo.targets Updates GitBlame to track AndroidPackVersion in eng/Versions.props.
build-tools/scripts/Configuration.Java.Interop.Override.in.props Deletes the unused template file previously consumed by Step_PrepareProps.

jonathanpeppers and others added 3 commits June 9, 2026 13:17
Configuration.props no longer needs to import eng/Versions.props itself.
In every MSBuild path that imports Configuration.props, Directory.Build.props
has already been loaded (either by MSBuild auto-load, or by the explicit
<Import Project="..\Directory.Build.props" /> in
external/xamarin-android-tools.override.props). Since Directory.Build.props
imports eng/Versions.props, the properties are always available.

This means there is no duplicate-import scenario, so the
_XAVersionsPropsImported sentinel can be removed too.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
It is OS-conditioned, not version-shaped, so it does not belong in
eng/Versions.props. Mirror the same 3-line block inline in
external/Java.Interop.override.props (as a private _MicrosoftAndroidSdkPackName
so it cannot leak into the Java.Interop build) to keep Versions.props limited
to pure version values.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sits next to AndroidPackVersion now, where it logically belongs. Updated
Documentation/guides/HowToBranch.md to reflect the new location.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
Member Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

jonathanpeppers and others added 3 commits June 9, 2026 19:06
…e-step-prepareprops

# Conflicts:
#	Directory.Build.props
CodeBehindTests.PrepareProject copies the repo Directory.Build.props into
a per-test temp root so the synthesized project under temp/CodeBehind/...
sees our shared MSBuild props. After this PR, Directory.Build.props
unconditionally imports eng/Versions.props, so the copy must include that
file too -- otherwise MSB4019 fires on every CodeBehindTests build:

  Directory.Build.props(3,3): error MSB4019: The imported project
  ".../temp/CodeBehind/.../eng/Versions.props" was not found.

CopyFile already creates intermediate directories, so a single extra line
that places it under tempRoot/eng/Versions.props is sufficient.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Accidentally rolled back in d459a69 by `git add -A` while the submodule
worktree still pointed at the pre-merge commit. The merge with main had
correctly taken b881d21 from origin/main; this re-applies that pointer.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers jonathanpeppers added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jun 10, 2026
@simonrozsival simonrozsival merged commit ee0392c into main Jun 11, 2026
40 checks passed
@simonrozsival simonrozsival deleted the jonathanpeppers/remove-step-prepareprops branch June 11, 2026 08:31
jonathanpeppers added a commit that referenced this pull request Jun 12, 2026
### Context

`Get_Omnisharp_Json` in `Step_GenerateFiles` substituted two placeholders into `build-tools/scripts/omnisharp.json.in` and wrote `omnisharp.json` at the repo root for OmniSharp / VS Code C# extension users. The generated file was always `.gitignore`d and **nothing in the repo, build, or CI consumes it** — it was purely a local-dev convenience.

Anyone who actually wants an `omnisharp.json` can keep their own local copy (it remains gitignored). Removing this generation slice is another small step in the slow xaprepare reduction, continuing the pattern from #11568, #11580, #11608, and #11613.

### Audit

Before this change `git grep -in "omnisharp"` returned five hits. After it returns only one — the unrelated MSBuild-context guard in `xaprepare.csproj` that prevents xaprepare's targets from importing under OmniSharp's MSBuild process:

```
build-tools/xaprepare/xaprepare/xaprepare.csproj:52:
  <Import Project="xaprepare.targets" Condition=" $(MSBuildToolsPath.IndexOf('omnisharp')) < 0 " />
```

That guard is intentional and is **not** touched by this PR.

### Changes

- `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs`: drop the `Get_Omnisharp_Json (context)` entry from the generated-files list and delete the `Get_Omnisharp_Json` method.
- Delete `build-tools/scripts/omnisharp.json.in`.

The shared properties used by the deleted method (`MicrosoftDotnetSdkInternalPackageVersion`, `DotNetPreviewPath`) are still referenced by `Step_InstallDotNetPreview` and `xaprepare.targets`, so they remain.

### Verification

- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug` — 0 warnings, 0 errors.
- `git grep -in "omnisharp"` — returns only the unrelated `xaprepare.csproj` guard described above.
- No `Documentation/` references to omnisharp; no `.vscode/` folder in the repo.
- Diff: 3 files, 35 deletions, 0 additions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jun 25, 2026
Mirrors #11608 (which checked in `Mono.Android.Apis.projitems` the same way). See also #11568, #11580, #11613, #11631, #11657, #11658.

## What

`build-tools/scripts/Ndk.projitems.in` was a template with `@NDK_*@` placeholders that the `Get_Ndk_projitems` generator in xaprepare filled in from constants in `BuildAndroidPlatforms.cs`. Those substitution values only change on rare NDK bumps, so generating the file on every build adds no value.

This PR checks in the resolved file as a static `build-tools/scripts/Ndk.projitems` and removes the generator.

## Changes

- **Add** `build-tools/scripts/Ndk.projitems` — the static, checked-in file. Rather than hardcoding values, it sources them from the existing properties in `Configuration.props` (which is imported before `Ndk.targets`):
  - `AndroidNdkVersion` → `$(_XAAndroidNdkRelease)`
  - `AndroidNdkPkgRevision` → `$(_XAAndroidNdkPkgRevision)`
  - the per-ABI `AndroidNdkApiLevel_*` → `$(AndroidMinimumDotNetApiLevel)`

  So there is nothing to keep in sync on an NDK/API bump.
- **`build-tools/scripts/Ndk.targets`** — point `ProjitemsFile` at the new in-tree location (`$(MSBuildThisFileDirectory)Ndk.projitems`) instead of `bin/Build$(Configuration)/Ndk.projitems`.
- **Delete** `build-tools/scripts/Ndk.projitems.in`.
- **`Step_GenerateFiles.cs`** — remove the `Get_Ndk_projitems` method and its dispatch entry.
- **`Configurables.cs`** — update a doc comment reference from `Ndk.projitems.in` → `Ndk.projitems`.

### Simplifications (from review)

- **Collapsed the dead legacy/NET API-level split.** The legacy 32-bit minimum API level used to be lower than the .NET minimum, but they are identical now. Removed the two per-ABI properties that nothing references (`AndroidNdkApiLevel_Arm`, `AndroidNdkApiLevel_X86_Legacy`). The `arm64-v8a`/`x86_64` properties are kept because shipped targets (`Build.Tasks.targets`, `Common.props.in`, `NativeAOT.targets`) still consume them by name.
- **Removed the `ApiLevelNET` item metadata.** `ApiLevelNET` was the .NET (.NET 6+) Android minimum API level vs. the legacy Xamarin.Android/Mono `ApiLevel`; the two are identical now and this repo is .NET-only. Its only consumer was `src/native/common/libunwind/libunwind-xamarin.targets`, which now reads `ApiLevel`. Dropped `ApiLevelNET` from all four `AndroidSupportedTargetJitAbi` items.

The NDK constants in `BuildAndroidPlatforms.cs` are intentionally left untouched — they're still consumed by `Get_XABuildConfig_cs` and the cmake presets generator.

## Verification

- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug` → 0 errors / 0 warnings.
- Evaluated the import chain via a standalone MSBuild harness (importing the real `Configuration.props`); it produces all four `AndroidSupportedTargetJitAbi` items with `ApiLevel`=24 and the expected `AndroidRID` metadata, matching prior generator output (NDK `28c` / pkg `28.2.13676358`).
- Audits clean: `git grep Ndk.projitems.in`, `git grep Ndk_projitems`, `git grep ApiLevelNET`, and the old `bin/Build$(Configuration)/Ndk.projitems` path all return 0 hits.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jun 26, 2026
Many xaprepare provisioning steps have been removed over the past year (#11332, #11348, #11399, #11440, #11441, #11636 and follow-up cleanups in #11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737). The supporting scaffolding around those steps was left behind. This PR removes the verified-dead pieces in two passes.

## Files removed (first pass — original audit)

| File | Justification |
| --- | --- |
| `Application/TestAssembly.cs` | Orphan test infra; only referenced by `TestAssemblyType.cs`. |
| `Application/TestAssemblyType.cs` | Only referenced by `TestAssembly.cs`. |
| `Application/StepWithDownloadProgress.cs` | No subclasses remain. |
| `Application/NDKTool.cs` | NDK provisioning moved to MSBuild in #11440. Last consumer was the also-dead `Configurables.NDKTools` collection (removed below). |
| `ToolRunners/SnRunner.cs` | Strong-naming tool runner; never instantiated. |
| `ToolRunners/SnRunner.OutputSink.cs` | Partial sibling of `SnRunner`. |
| `ToolRunners/CMakeRunner.cs` | Never instantiated. |
| `ToolRunners/CMakeRunner.OutputSink.cs` | Partial sibling of `CMakeRunner`. |

## Files removed (second pass — repo-wide re-audit)

| File | Justification |
| --- | --- |
| `ToolRunners/MakeRunner.Linux.cs` | Partial of `MakeRunner`; type never instantiated. |
| `ToolRunners/MakeRunner.MacOS.cs` | Partial of `MakeRunner`. |
| `ToolRunners/MakeRunner.OutputSink.Unix.cs` | Partial of `MakeRunner`. |
| `ToolRunners/MakeRunner.Unix.cs` | Partial of `MakeRunner`. |
| `ToolRunners/MSBuildRunner.cs` | Never instantiated. |
| `ToolRunners/MSBuildRunner.OutputSink.cs` | Partial sibling of `MSBuildRunner`. |
| `ToolRunners/NinjaRunner.cs` | Never instantiated. |
| `ToolRunners/NinjaRunner.OutputSink.cs` | Partial sibling of `NinjaRunner`. |
| `Application/ScenarioNoStandardEndSteps.cs` | Abstract class with zero subclasses. |

## Cascading cleanup

- `ConfigAndData/Configurables.cs` — removed the dead `NDKTools` `List<NDKTool>` collection (lines 132–145). Rest of the file unchanged.

## Removed from initial deletion list after verification

- `Application/Extensions.DictionaryOfProgramVersionParser.cs` — initial name-only audit flagged it as dead, but its `Add` extension method is consumed via dictionary collection-initializer syntax in `Application/VersionFetchers.cs`. The consumer never references the static class by name, which is why the first audit missed it. The file stays.
- `Scenarios/Scenario_Required.cs` — looks unreferenced by static grep, but `Scenario` subclasses are reflectively discovered via the `[Scenario]` attribute in `Context.cs` (`Utilities.GetTypesWithCustomAttribute<ScenarioAttribute> ()`). Live. The file stays.

## Verification

- `git grep -n -w <TypeName>` for each deleted type now returns 0 real hits (only unrelated `"TestAssembly"` string literals in `tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/` remain — those are assembly-name strings, not the C# type).
- `dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug` → 0 warnings, 0 errors.

## Deferred follow-up

The csproj conditionally excludes `*MacOS*` files from compilation when `HostOS != Darwin`, so static dead-code analysis from a Windows/Linux host can't see whether the macOS-only consumers are themselves live. These candidates need verification on a Mac host (or a build matrix) before deletion:

- `Application/PkgProgram.MacOS.cs`
- `Application/HomebrewProgram.MacOS.cs`
- `ToolRunners/BrewRunner.MacOS.cs`
- `ToolRunners/PkgutilRunner.MacOS.cs`
- `ConfigAndData/Dependencies/MacOS.cs`
jonathanpeppers added a commit that referenced this pull request Jun 27, 2026
…ct (#11760)

Continues the incremental dismantling of `xaprepare` (see #11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737, #11740). Two more generator methods come out, and the work they did moves into a small dedicated MSBuild project.

## What changes

Two xaprepare generators in `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs` are deleted:

* `Get_Cmake_XA_Build_Configuration` — produced `bin/Build$(Configuration)/xa_build_configuration.cmake`, included by `src/native/CMakeLists.txt`.
* `Get_Cmake_Presets` (and its `GetCmakePresetsCommon` helper) — produced `src/native/CMakePresets.json`, consumed by the `cmake` preset invocations in `src/native/native.targets`.

Both are now generated by a new project:

* **`src/native/cmake-config/cmake-config.csproj`** (`Microsoft.Build.NoTargets`) hosts `_GenerateCMakeFiles`, which uses the existing `ReplaceFileContents` MSBuild task to substitute the placeholders in `build-tools/scripts/xa_build_configuration.cmake.in` and `src/native/CMakePresets.json.in`.
* `native-mono.csproj`, `native-clr.csproj`, and `native-nativeaot.csproj` each `<ProjectReference>` this project.

### Why a dedicated project (not just a target in `native.targets`)

The three native csproj share two output files (`bin/Build$(Configuration)/xa_build_configuration.cmake` and `src/native/CMakePresets.json`). Hosting the generator in `native.targets` would either:

* Race on the shared outputs under parallel msbuild (`/m`), or
* Require a `'$(MSBuildProjectName)' == 'native-mono'` gate -- which breaks isolated `dotnet build native-clr.csproj` on a clean tree (the gitignored output files would never get generated).

A dedicated project with three incoming `<ProjectReference>`s solves both: single producer, and project-reference ordering guarantees the outputs exist before any consumer's `cmake` preset call -- including for isolated single-csproj builds.

### Incremental correctness

`_GenerateCMakeFiles` declares fully-anchored `Inputs`:

* `build-tools/scripts/xa_build_configuration.cmake.in`
* `src/native/CMakePresets.json.in`
* `Configuration.props` (`AndroidNdkDirectory`, `NinjaPath`, `MicrosoftAndroidSdkOutDir`, `XAPackagesDir`, `AndroidMinimumDotNetApiLevel`)
* `Directory.Build.props` (`TestOutputDirectory`)
* `eng/Versions.props` (`MicrosoftNETCoreAppRefPackageVersion`)

so editing any of those re-runs the target; a no-change rebuild skips it. (Note: `$(MSBuildAllProjects)` is intentionally **not** used -- it does not include imported `.props` files for SDK-style projects since MSBuild 16.0; verified empirically.)

### Cascading deletions in xaprepare

* `Configurables.NativeSourcesDir` (was used only by `Get_Cmake_Presets`).
* All eight `Configurables.Paths.NetcoreAppRuntimeAndroid*` / `CoreClrAppRuntimeAndroid*` properties (+ backing fields + the `GetNetcoreAppRuntimePath` / `GetCoreClrAppRuntimePath` helpers) -- the new MSBuild target reads `$(XAPackagesDir)` / `$(MicrosoftNETCoreAppRefPackageVersion)` directly.
* The `Get_Cmake_*` entries in `Step_GenerateFiles.GetFilesToGenerate`.

`BuildAndroidPlatforms.NdkMinimumAPI` / `NdkMinimumAPILegacy32` are kept -- still used by `Get_XABuildConfig_cs` (a separate generator for a future PR).

### What stays

The `.in` template files are unchanged and still tracked in git -- the new MSBuild target reads them. The other generators in `Step_GenerateFiles.cs` (`Get_SourceLink_Json`, `Get_Configuration_OperatingSystem_props`, `Get_XABuildConfig_cs`, `AddOSSpecificSteps`) are out of scope and untouched.

## Verification

On Windows:

* `build.cmd Prepare -c Debug`
* `dotnet-local.cmd build src\native\native-mono.csproj -c Debug` -> 0 errors, generates both files
* `dotnet-local.cmd build src\native\native-clr.csproj -c Debug` -> 0 errors (incl. clean-tree isolated build)
* `dotnet-local.cmd build src\native\native-nativeaot.csproj -c Debug` -> 0 errors
* `dotnet-local.cmd build build-tools\xaprepare\xaprepare\xaprepare.csproj -c Debug` -> 0 errors

Incremental behaviour verified by walking through MSBuild diagnostic output:

* No-change rebuild: `Skipping target "_GenerateCMakeFiles" because all output files are up-to-date`.
* `touch eng/Versions.props` + rebuild: `Building target "_GenerateCMakeFiles" completely`, outputs re-written.

The generated `CMakePresets.json` and `xa_build_configuration.cmake` were diffed against the xaprepare baselines captured before the deletion; only the path separator normalisation (forward slashes throughout) differs, which both CMake and JSON accept on every platform.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jun 30, 2026
### Context

After #11636 (dotnet provisioning step removed) and #11731 (test-deps scenarios removed), `Context.AutoProvision` is `false` by default everywhere except hand-run dev provisioning, which is no longer in use. The per-OS package lists are populated at `OS.Init()` time but `EnsureDependencies` is effectively a no-op:

- `OS.EnsureDependencies()` returns early when `AutoProvision` is false (the default),
- nothing else in the codebase reads from the `Program` derivatives' install/uninstall paths,
- the `BuildToolsInventory` writer remains driven only from `EssentialTools.MacOS.cs` (homebrew version detection).

The `OS.Init() / InitializeDependencies() / EnsureDependencies()` machinery on `OS.cs` itself is intentionally **left in place** here — that's a larger refactor for a follow-up PR. This PR only strips the now-vestigial package-list data and the program/runner classes that fed it.

### Files deleted (Phase F — macOS, 4 files)

- `Application/HomebrewProgram.MacOS.cs`
- `Application/PkgProgram.MacOS.cs`
- `ToolRunners/BrewRunner.MacOS.cs`
- `ToolRunners/PkgutilRunner.MacOS.cs`

### Files deleted (Phase G — Linux, 5 files)

- `Application/Program.Linux.cs` (`LinuxProgram` base — orphan after subclasses go)
- `Application/Program.ArchLinux.cs`
- `Application/Program.DebianLinux.cs`
- `Application/Program.FedoraLinux.cs`
- `Application/Program.GentooLinux.cs`

### Files deleted (Phase 3 — orphan)

- `Application/IBuildInventoryItem.cs` (only implementor was `HomebrewProgram`; `BuildToolsInventory` itself stays, populated directly by `EssentialTools.MacOS.cs`).

### Files reduced to empty stubs

`ConfigAndData/Dependencies/`:
- `MacOS.cs` — `InitializeDependencies()` no-op (was Homebrew formula list + git fallback).
- `Linux.Arch.cs` — class kept (referenced by `distroMap`); package list removed.
- `Linux.Fedora.cs` — same.
- `Linux.Gentoo.cs` — same.
- `Linux.DebianCommon.cs` — common Debian/Ubuntu package list removed; `Flavor = "Debian"` kept.
- `Linux.UbuntuCommon.cs` — `libtoolPackages` + `NeedLibtool` virtual + `InitOS` override removed (all dead).
- `Linux.Debian.cs` — all per-version package lists (`packages`, `packagesPre10`, `packagesPreTrixie`, `packagesTrixieAndLater`, `packages10AndNewerBuildBots`) removed; release/codename detection (`EnsureVersionInformation`, `DebianUnstableVersionMap`, `IsDebian10OrNewer`, etc.) preserved as conservative scope.
- `Linux.Ubuntu.cs` — `preCosmicPackages`, `cosmicPackages`, `preDiscoPackages` lists + `NeedLibtool` override removed; `UbuntuRelease` + `EnsureVersionInformation` preserved.
- `Linux.Mint.cs` — `NeedLibtool` override removed (the property is gone from the base).

`ConfigAndData/Dependencies/Windows.cs` was already a no-op stub — no edit.

### Verification

Orphan audit (each `git grep -nw <Type> -- 'build-tools/xaprepare/*'` reports **0 hits**):

- `HomebrewProgram`, `PkgProgram`, `BrewRunner`, `PkgutilRunner`
- `ArchLinuxProgram`, `DebianLinuxProgram`, `FedoraLinuxProgram`, `GentooLinuxProgram`, `LinuxProgram`
- `IBuildInventoryItem`

Build:

```
dotnet build build-tools\xaprepare\xaprepare\xaprepare.csproj -c Debug
Build succeeded.  0 Warning(s)  0 Error(s)
```

### Out of scope (follow-up)

- Removing the abstract `OS.InitializeDependencies()` declaration and the surrounding `EnsureDependencies()` machinery from `OperatingSystems/OS.cs`.
- `VersionFetchers` / `ProgramVersionParser` / `RegexProgramVersionParser` / `SevenZipVersionParser` / `Extensions.DictionaryOfProgramVersionParser.cs` are kept — `Utilities.GetProgramVersion` still queries them from `Program.cs`, `ToolRunner.cs`, `EssentialTools.MacOS.cs`, and `OperatingSystems/MacOS.cs` (brew detection).

### Precedent

#11568, #11580, #11608, #11613, #11631, #11657, #11658, #11731, #11732, #11733, #11737, #11740, #11760
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11826)

## Summary

Moves `XABuildConfig.cs` generation out of `xaprepare` and into a new strong-named class library at `src/AndroidBuildConfig/AndroidBuildConfig.csproj` that produces `AndroidBuildConfig.dll`.

This continues the incremental removal of `xaprepare`, following the precedent set by `cmake-config.csproj` (#11760) and the recent batch #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11803, #11821, #11825.

It also fixes a long-standing wart: previously `XABuildConfig.cs` was `<Compile Include>`'d into three different assemblies (`Xamarin.Android.Build.Tasks`, `Xamarin.ProjectTools`, and `Xamarin.Android.Build.Tests`), so every test that mentioned `XABuildConfig` produced a `CS0436` "type conflicts with imported type" warning — about **22** of them.

Wrapping the type in its own assembly collapses it to a single definition that every consumer references normally. After this change `Xamarin.Android.Build.Tests` builds with **7** warnings (none for `XABuildConfig`).

## How it works

`src/AndroidBuildConfig/AndroidBuildConfig.csproj`:

- `Microsoft.NET.Sdk` / `netstandard2.0`, strong-named with `product.snk`.
- `ProjectReference`s `Xamarin.Android.Tools.AndroidSdk` (for the `AndroidTargetArch` enum used by the template).
- `<UsingTask>`s `ReplaceFileContents`, `GitCommitHash`, and `GitBranch` from `$(PrepTasksAssembly)`, all with `TaskFactory="TaskHostFactory" Runtime="NET"` per repo convention.
- The `_GenerateXABuildConfig` target runs `BeforeTargets="BeforeCompile;CoreCompile"`, computes every substitution from MSBuild properties already exposed by `Configuration.props` (NDK major/minor/micro via `$(_XAAndroidNdkPkgRevision.Split('.'))`, API levels via `Split`/`Contains`, full commit hash via `GitCommitHash.CommitHash`, branch via `GitBranch.Branch`), and writes the file to `$(IntermediateOutputPath)XABuildConfig.cs`. The `<Compile Include>` lives inside the target so it resolves at execution time, when `IntermediateOutputPath` is final.
- `XABuildConfig` is now `public static class` instead of `internal static class`.

The three consumer csprojs lose their `<Compile Include="…XABuildConfig.cs" />` and now have a normal `<ProjectReference Include="…AndroidBuildConfig.csproj" />` (no `ReferenceOutputAssembly="False"`).

`build-tools/installers/create-installers.targets` ships `AndroidBuildConfig.dll` + `.pdb` alongside `Xamarin.Android.Build.Tasks.dll`.

## xaprepare cleanup

Removed dead code that only existed to feed the old `Get_XABuildConfig_cs` step:

- `Step_GenerateFiles.Get_XABuildConfig_cs` and its `GetMajor` / `GetMinor` locals
- `BuildInfo`: `NDKRevision`, `NDKVersionMajor`, `NDKVersionMinor`, `NDKVersionMicro`, `NDKVersion`, `XACommitHash`, `XABranch`, `GatherGitInfo`, `DetermineXACommitInfo`, `cachedNdkVersion`
- `Context`: the `if (SelectedScenario.NeedsGitBuildInfo) { await BuildInfo.GatherGitInfo … }` block
- `Scenario.NeedsGitBuildInfo` (and the `NeedsGitBuildInfo = true;` setters in `Scenario_Standard` and `Scenario_Required`)
- `BuildAndroidPlatforms.cs` — entire file (only contained constants used by the deleted code)
- `Utilities.ParseAndroidPkgRevision`
- `GitRunner.GetTopCommitHash` and `GitRunner.GetBranchName` (class retained — still used by `BuildInfo.DetermineLastVersionChangeCommit`)

## Files

**Added**
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`

**Renamed/moved**
- `build-tools/scripts/XABuildConfig.cs.in` → `src/AndroidBuildConfig/XABuildConfig.cs.in` (`static class` → `public static class`)

**Modified**
- `src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Xamarin.ProjectTools.csproj`
- `src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj`
- `build-tools/installers/create-installers.targets`
- `build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs`
- `build-tools/xaprepare/xaprepare/Application/BuildInfo.cs`
- `build-tools/xaprepare/xaprepare/Application/Context.cs`
- `build-tools/xaprepare/xaprepare/Application/Scenario.cs`
- `build-tools/xaprepare/xaprepare/Application/Utilities.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Standard.cs`
- `build-tools/xaprepare/xaprepare/Scenarios/Scenario_Required.cs`
- `build-tools/xaprepare/xaprepare/ToolRunners/GitRunner.cs`
- `build-tools/xaprepare/README.md`

**Deleted**
- `build-tools/xaprepare/xaprepare/ConfigAndData/BuildAndroidPlatforms.cs`

## Verification

- `AndroidBuildConfig.csproj`: 0 warnings, 0 errors.
- `Xamarin.Android.Build.Tasks.csproj`: 0 errors, 85 pre-existing unrelated warnings (none for `XABuildConfig`).
- `Xamarin.Android.Build.Tests.csproj`: 0 errors, **7** warnings — down from ~22; all `CS0436 XABuildConfig` conflicts eliminated.
- `xaprepare.csproj`: 0 warnings, 0 errors.
- Generated `XABuildConfig.cs` is semantically identical to the pre-change xaprepare output. The only token difference is the intentional `static class` → `public static class`; everything else (NDK split, API-level major/minor split, supported-ABIs semicolon list, full commit hash, branch name, etc.) matches the previous baseline byte-for-byte.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
…11825)

Continues the incremental removal of `xaprepare` by moving the
`cgmanifest.json` generator out of the C# step
`Step_GenerateCGManifest` and into a YAML `pwsh:` step that runs only
on CI.

The file is consumed exclusively by the Azure DevOps Component
Governance Detection task (auto-injected on internal pipelines by
`eng/common/core-templates/job/job.yml`). It is not consumed by any
in-repo build target, so generating it from the C# Prepare step is no
longer necessary.

We cannot drop the file outright: `eng/common` ships CG infrastructure
but it is not yet wired to auto-discover submodules in our pipelines,
so the explicit `cgmanifest.json` is still the source of truth.

Files:
* Added: `build-tools/automation/yaml-templates/generate-cgmanifest.yaml`
* Modified: `build-windows-steps.yaml`, `build-macos-steps.yaml`,
  `build-linux-steps.yaml`, `commercial-build.yaml` (call the new
  template after the Prepare/`make jenkins` step)
* Modified: `Scenario_Standard.cs` (drop registration)
* Modified: `GitRunner.cs` (remove now-unused `ConfigList` and
  `SubmoduleStatus` methods)
* Deleted: `Step_GenerateCGManifest.cs`

Verification: byte-for-byte diff of the YAML-generated
`cgmanifest.json` against the previous C# output on Debug:

    Baseline=3144 New=3144
    Total byte differences: 0

Precedent PRs in this stream: #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803,
#11821.

### Simplify generate-cgmanifest.yaml using ConvertTo-Json

Replace the hand-rolled StringBuilder JSON emission with PowerShell's
`ConvertTo-Json`. The output is no longer byte-identical to the
previous C# output (2-space indent instead of 4, and slightly
different whitespace), but it is still valid JSON matching the
component-detection-manifest schema. The Azure DevOps Component
Governance Detection task parses the file, so formatting does not
matter.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jul 1, 2026
On Windows, xaprepare's Step_GenerateFiles.Windows.cs writes
external/Java.Interop/bin/Build$(Configuration)/JdkInfo.props from
build-tools/xaprepare/xaprepare/Resources/JdkInfo.Windows.props.in.

But this file is immediately overwritten. The PrepareWindows.targets
Prepare flow runs, in order:

  1. `dotnet xaprepare -a` — writes JdkInfo.props (this code).
  2. `MSBuild Xamarin.Android.BootstrapTasks.sln` — does not read JdkInfo.props.
  3. `MSBuild src/workloads/workloads.csproj` — does not read JdkInfo.props.
  4. `CallTarget PrepareJavaInterop` → `dotnet build -t:Prepare Java.Interop.sln`
     → external/Java.Interop/build-tools/scripts/Prepare.targets → runs the
     `JdkInfo` MSBuild task → overwrites JdkInfo.props with its own generated
     content.

Nothing between step 1 and step 4 reads the file, and Java.Interop's Prepare
always regenerates it. Now that external/Java.Interop is in-tree, we can
safely delete the redundant write.

This is the smallest-diff removal:

  * Delete Step_GenerateFiles.Windows.cs (the AddOSSpecificSteps partial).
  * Delete Resources/JdkInfo.Windows.props.in.
  * In Step_GenerateFiles.cs, drop the `partial void AddOSSpecificSteps`
    declaration and collapse GetFilesToGenerate so `atBuildStart == false`
    returns null. Ctor surface (atBuildStart, onlyRequired) is unchanged so
    Scenario_Required.cs is unaffected.
  * In Scenario_Standard.cs, remove the AddEndSteps override — the only
    thing it did was schedule the now-empty Step_GenerateFiles(atBuildStart:
    false).

Preserved (future slices will address these):
  * Get_Configuration_OperatingSystem_props (D1).
  * OperatingSystems/*.cs and Context.OS.* surface.
  * PrepareWindows.targets, DotNet.targets, Java.Interop's Prepare.targets.

Verification:

  * dotnet build build-tools/xaprepare/xaprepare/xaprepare.csproj -c Debug
    → Build succeeded. 0 Warning(s). 0 Error(s).
  * build.cmd -t:Prepare -c Debug (Windows, cold tree) → succeeds; the file
    external/Java.Interop/bin/BuildDebug/JdkInfo.props exists.
  * Compare-Object of the resulting JdkInfo.props before vs after this
    change → byte-identical (1493 bytes, SHA256
    DE59A8061B7657831788FFED7BC1DEECA442E9181605083A4553DE7AC8C003A1),
    confirming Java.Interop's overwrite is what always ends up on disk.
  * Grep audit under build-tools/xaprepare/: no remaining references to
    Step_GenerateFiles.Windows, JdkInfo.Windows.props.in, or
    AddOSSpecificSteps.

Follows previous xaprepare deletion slices #11568, #11580, #11608, #11613,
#11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821,
#11825, #11826.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
simonrozsival pushed a commit that referenced this pull request Jul 3, 2026
…xaprepare project (#11959)

Follow-up to #11956, which moved the JDK half of `Configuration.OperatingSystem.props` to Java.Interop's `JdkInfo.props`. The remaining NDK / OS-info half has zero real consumers, so this PR:

1. Deletes the last generator template (`Configuration.OperatingSystem.props.in`).
2. Cascades through `Step_GenerateFiles`, both `Scenario_*` classes (which now had zero steps), and every supporting `OperatingSystems/`, `Context.*OS.cs`, `EssentialTools.*`, `ToolRunners/*`, `Configurables.*`, `Application/*`, and `Main.cs` file that only existed to feed the scenarios.
3. Deletes the whole `build-tools/xaprepare/` project.
4. Patches every integration point (`Makefile`, `PrepareWindows.targets`, `BuildEverything.mk`, CI YAML, docs) so `build.cmd -t:Prepare` and `make prepare` still work end-to-end.

## `Configuration.OperatingSystem.props.in` placeholder audit

| Placeholder | Consumers outside the `.in` file | Action |
| --- | --- | --- |
| `HostOsName` | none | drop |
| `HostOsFlavor` | none | drop |
| `HostOsRelease` | none | drop |
| `HostBits` | none (`ArchiveBase.HostBits` in `src/Xamarin.Installer.AndroidSDK/` is an unrelated C# property) | drop |
| `NdkLlvmTag` | none (the NDK toolchain OS tag is resolved elsewhere via `_NdkToolchainOSTag` in `androidsdk.targets`) | drop |
| `HostCpuCount` | only `Configuration.props:72` via `$(MakeConcurrency)` | drop |

## `$(MakeConcurrency)` audit

The only definition was `Configuration.props:72`. A repo-wide grep of `.targets`, `.props`, `.projitems`, `Makefile`, and `.mk` files found zero consumers of the MSBuild property. The `MakeConcurrency` hits under `build-tools/xaprepare/` were an unrelated C# `Context.MakeConcurrency` property.

**Result:** dropped the `MakeConcurrency` MSBuild property entirely (no `$([System.Environment]::ProcessorCount)` replacement needed) and removed the `$(MakeConcurrency)` bullet in `Documentation/building/configuration.md`.

## xaprepare integration audit (grep-confirmed, patched here)

| Location | Change |
| --- | --- |
| `build-tools/xaprepare/` (entire tree) | **deleted** — 86 tracked files |
| `Configuration.props` | dropped `<Import>` of the generated OS props, dropped `MakeConcurrency`, tidied the "between xaprepare and package creation tools" comment |
| `.gitignore` | dropped `Configuration.OperatingSystem.props` |
| `build-tools/scripts/PrepareWindows.targets` | removed `_XAPrepareExe`, `_XAPrepareStandardArgs`, `_BuildXAPrepare` target, and the `Exec dotnet $(_XAPrepareExe)` line. Repointed `Prepare` at `_InstallDotNet`. Kept the space-in-path guard, BootstrapTasks / workloads MSBuilds, and `PrepareJavaInterop` |
| `Makefile` | dropped `PREPARE_PROJECT`, `PREPARE_NET_FX`, `PREPARE_ARGS`, `PREPARE_MSBUILD_FLAGS`, `PREPARE_SCENARIO`, `PREPARE_CI_PR`, `PREPARE_CI`, `_PREPARE_CI_MODE_*`, `_PREPARE_ARGS`, and all their conditionals. Dropped the `dotnet run --project xaprepare.csproj` line from `prepare`. Deleted the `prepare-help` target |
| `build-tools/scripts/BuildEverything.mk` | `jenkins` no longer branches on `PREPARE_CI_PR`/`PREPARE_CI`; just `$(MAKE) prepare && $(MAKE) leeroy` |
| `.github/workflows/copilot-setup-steps.yml` | dropped now-unused `PREPARE_CI=1` |
| `build-tools/automation/azure-pipelines-apidocs.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-linux-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/build-macos-steps.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/commercial-build.yaml` | dropped `PREPARE_CI=1` |
| `build-tools/automation/yaml-templates/copy-extra-result-files.yaml` | dropped `**/Configuration.OperatingSystem.props` glob and the stale `Step_CopyExtraResultFilesForCI` xaprepare-step comment |
| `build-tools/automation/yaml-templates/generate-cgmanifest.yaml` | dropped the stale `Step_GenerateCGManifest` xaprepare-step comment |
| `build-tools/automation/yaml-templates/setup-jdk-variables.yaml` | renamed `$xaPrepareJdkPath` → `$xaJdkPath` for hygiene |
| `Documentation/workflow/HowToAddNewApiLevel.md` | rewrote the "Add New Platform" section to point at `<_PlatformPackage>` entries in `src/androidsdk/androidsdk.targets` instead of `AndroidToolchain.cs`; updated the `--android-sdk-platforms=all` recipe to `dotnet-local build src/androidsdk/androidsdk.csproj -p:AndroidSdkPlatforms=all` |
| `Documentation/building/unix/dependencies.md` | JDK-version link now points at `$(MicrosoftOpenJDKVersion)` in `/Configuration.props` instead of the deleted `Configurables.cs` |
| `Documentation/building/configuration.md` | removed the `$(MakeConcurrency)` bullet |

**Historical breadcrumb comments left as-is** (still accurate and useful for git-archaeology):

- `.github/skills/update-tpn/SKILL.md`
- `src/AndroidBuildConfig/AndroidBuildConfig.csproj`
- `src/androidsdk/androidsdk.targets`
- `src/native/cmake-config/cmake-config.csproj`
- `src/workloads/workloads.csproj`

## Verification

- `build.cmd Prepare` — succeeded end-to-end on Windows (0 warnings, 0 errors). The trimmed `Prepare` target ran through `_InstallDotNet`, the space-in-path guard, `Xamarin.Android.BootstrapTasks.sln`, `src/workloads/workloads.csproj`, and `PrepareJavaInterop`.
- `dotnet build src\Xamarin.Android.Build.Tasks\Xamarin.Android.Build.Tasks.csproj -c Debug` — 0 errors (93 pre-existing warnings from `src/Mono.Android/` and generated MCW, unrelated to this change).
- Repo-wide grep for `HostOsName`, `HostOsFlavor`, `HostOsRelease`, `HostCpuCount`, `NdkLlvmTag`, and the MSBuild `MakeConcurrency` property — clean.
- Repo-wide grep for `xaprepare` — clean apart from the five intentional historical breadcrumb comments listed above.

## Diff stat

102 files changed, 25 insertions(+), 7891 deletions(-).

## Precedent chain

Continues the multi-slice teardown started by #11568, #11580, #11608, #11613, #11631, #11731, #11732, #11733, #11737, #11740, #11760, #11803, #11821, #11825, #11826, #11945, #11946, #11956.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants